import { computed, defineComponent, onMounted, onUnmounted, PropType, reactive, ref, watch } from 'vue'
import Broadcast from './index.module.scss'

export enum Orientation { Top, Left}

export default defineComponent({
  name: 'Broadcast',

  props: {
    broadcastData: {
      type: Array,
      default: () => []
    },
    orientation: {
      type: Number as PropType<Orientation>,
      default: Orientation.Top
    },
    time: { // 间隔时间
      type: Number,
      default: 2000
    }
  },

  setup(props) {
    const broadcastRef = ref(null as Nullable<HTMLElement>)
    const timer = ref<null | number>(null)
    const current = ref(0)
    const broadcast = reactive({
      boxStyle: '',
      intervalStyle: '',
      anStyle: '',
      count: 0
    })

    const currentBroadcast = computed(() => {
      const data = props.broadcastData || []
      return {
        pre: data[current.value],
        next: data[current.value + 1] ? data[current.value + 1] : data[0]
      }
    })

    const broadcastAn = () => {
      if (broadcastRef.value) {
        timer.value = setTimeout(() => {
          timer.value = null
          current.value += 1
          if (current.value === props.broadcastData.length) current.value = 0
          broadcast.count += 1
          const { offsetWidth, offsetHeight } = broadcastRef.value as HTMLElement
          if (props.orientation === Orientation.Top) {
            broadcast.intervalStyle = `width: ${offsetWidth}px;height: ${(broadcast.count - 1) * offsetHeight}px`
            broadcast.anStyle = `transform: translate3d(0, -${broadcast.count * offsetHeight}px, 0)`
          } else {
            broadcast.intervalStyle = `width: ${(broadcast.count - 1) * offsetWidth}px; height: ${offsetHeight}px`
            broadcast.anStyle = `width: ${(broadcast.count + 2) * offsetWidth}px; transform: translate3d(-${broadcast.count * offsetWidth}px, 0, 0)`
          }
          broadcast.boxStyle = `width: ${offsetWidth}px`
        }, props.time)
      }
    }

    const anEnd = () => {
      if (!timer.value) broadcastAn()
    }

    watch(() => props.broadcastData, () => {
      current.value = 0
      anEnd()
    })

    onMounted(() => {
      anEnd()
    })

    onUnmounted(() => {
      if(timer.value) clearTimeout(timer.value)
    })

    return () => (
      <div class={Broadcast.broadcast} ref={broadcastRef}>
        <div class={Broadcast.animate} onTransitionend={anEnd} style={broadcast.anStyle}>
          <div style={broadcast.intervalStyle} />
          <p class={Broadcast.box} style={broadcast.boxStyle} v-html={currentBroadcast.value.pre} />
          <p class={Broadcast.box} style={broadcast.boxStyle} v-html={currentBroadcast.value.next} />
        </div>
      </div>
    )
  }
})
